package com.flying.invest.monitor.service;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.flying.common.util.Codes;
import com.flying.common.util.DateUtils;
import com.flying.common.util.DateUtils.Field;
import com.flying.framework.annotation.Param;
import com.flying.framework.annotation.Service;
import com.flying.framework.context.ServiceContext;
import com.flying.framework.data.Data;
import com.flying.framework.service.AbstractService;
import com.flying.invest.account.service.AccountNetValueService;
import com.flying.invest.account.service.AccountService;
import com.flying.invest.assets.service.AssetsPriceService;
import com.flying.invest.assets.service.AssetsService;
import com.flying.invest.invest.model.InvestmentTransaction.Method;
import com.flying.invest.invest.model.InvestmentTransaction.Status;
import com.flying.invest.invest.service.InvestmentService;
import com.flying.invest.invest.service.InvestmentTransactionService;
import com.flying.invest.strategy.service.StrategyPriceChangeService;
import com.flying.invest.strategy.service.StrategyService;
import com.flying.invest.summary.service.SummaryMoneyDailyService;

@Service(value="HomeMonitorService", desc="首页监控")
public class HomeMonitorService extends AbstractService {
	private final static NumberFormat nf = new DecimalFormat("###,###");
	private final static NumberFormat nf2 = new DecimalFormat("###,###.00");
	private final static NumberFormat nf4 = new DecimalFormat("###,###.0000");
	
	private AccountService accountService;
	private AccountNetValueService netvalueService;
	private SummaryMoneyDailyService summaryService;
	private InvestmentTransactionService transactionService;
	private AssetsService assetsService;
	private AssetsPriceService assetsPriceService;
	private StrategyService strategyService;
	private StrategyPriceChangeService changeService;
	private InvestmentService investService;
	
	public void setAccountService(AccountService s) {
		this.accountService = s;
	}
	public void setAccountNetValueService(AccountNetValueService s) {
		this.netvalueService = s;
	}
	public void setSummaryMoneyDailyService(SummaryMoneyDailyService s) {
		this.summaryService = s;
	}
	public void setInvestmentTransactionService(InvestmentTransactionService s) {
		this.transactionService = s;
	}
	public void setAssetsService(AssetsService s) {
		this.assetsService = s;
	}
	public void setStrategyService(StrategyService s) {
		this.strategyService = s;
	}
	public void setStrategyPriceChangeService(StrategyPriceChangeService s) {
		this.changeService = s;
	}
	public void setInvestmentService(InvestmentService s) {
		this.investService = s;
	}
	public void setAssetsPriceService(AssetsPriceService s) {
		this.assetsPriceService = s;
	}
	
	private String getStockInfo(String code) {
		var template = "%s(%s) 当前<font color='red'>%s</font>点，今年涨跌<font color='red'>%s%%</font>；";
		var s = this.assetsService.findByCode(code);
		var first = DateUtils.getDate(DateUtils.get(new Date(), Field.YEAR) , 0, 1);
		var dates = new String[] {DateUtils.formatDate(first, "yyyy-MM-dd"), DateUtils.formatDate(new Date(), "yyyy-MM-dd")};
		var f = this.assetsPriceService.findAllASC(s.getAssetsId(), dates, 0, 10).getRows().get(0);
		var l = this.assetsPriceService.findAllDESC(s.getAssetsId(), dates, 0, 10).getRows().get(0);
		return String.format(template, s.getName(), s.getCode(), l.getPrice(), nf2.format((l.getPrice() - f.getPrice()) * 100 / f.getPrice()));
	}

	public Data getMonitorResult(@Param("user_id") Long user_id) throws Exception {
		var principal = ServiceContext.getContext().getPrincipal();
		var result = new Data();
		var list = new ArrayList<String>();
		//大盘
		list.add(this.getStockInfo("000001")+this.getStockInfo("000985")+this.getStockInfo("000300"));
		//row1
		var accounts = this.accountService.findAll(user_id, 0, 100).getRows();
		var totalShares = accounts.stream().filter(x -> x.getShares() != null).mapToDouble(x -> x.getShares()).sum();
		var totalAmount = accounts.stream().filter(x -> x.getTotalAmount() != null).mapToDouble(x -> x.getTotalAmount()).sum();
		try {
			var year = DateUtils.getYear(new Date());
			var firstDayOfYear = year+"-01-01";
			var yearNetValue = this.netvalueService.findByUserId(Long.parseLong(principal.getId()), new String[] {firstDayOfYear, firstDayOfYear}, 0, 10).getRows().get(0);
			var template1 = "累计本金 <font color='red'>%s</font> 元，现市值 <font color='red'>%s</font> 元，"+
					"本年浮盈浮亏 <font color='red'>%s</font> 元，本年净值 <font color='red'>%s</font> 元，累计净值 <font color='red'>%s</font> 元";
			var currentNetValue = totalAmount/ totalShares;
			var yearDateNetValue = yearNetValue.getTotalAmount() / yearNetValue.getShares();
			var row1 = String.format(template1, nf.format(totalShares), nf.format(totalAmount), nf.format(totalAmount - yearNetValue.getTotalAmount()), 
					nf4.format(currentNetValue / yearDateNetValue), nf4.format(currentNetValue));
			list.add(row1);
		}catch (Exception e) {
			System.out.println(e);
		}
		
		//row2
		var template21 = "债券和现金共 <font color='red'>%s</font> 元，占总市值 <font color='red'>%s %%</font> ，监控正常";
		var template22 = "债券和现金共 <font color='red'>%s</font> 元，占总市值 <font color='red'>%s %%</font> ，低于安全阀值 <font color='red'>%s %%</font> ，监控异常报警，请尽快调整";
		var rows = this.summaryService.findAssetsTypeReport(user_id, DateUtils.formatDate(new Date(), "yyyy-MM-dd")).getRows(Codes.ROWS);
		var totalCashier = rows.stream().filter(x -> ((Long)x.get("type_id") == 0 || (Long)x.get("type_id") == 53))
				.mapToDouble(x -> (Double)x.get("y")).sum();
		final String row2;
		var cashierRate = totalCashier / totalAmount * 100;
		if(cashierRate > 20) {
			row2 = String.format(template21, nf.format(totalCashier), nf2.format(cashierRate));
		} else {
			row2 = String.format(template22, nf.format(totalCashier), nf2.format(cashierRate), nf2.format(20));
		}
		list.add(row2);
		//row3
		var template31 = "单一股票 <font color='red'>%s</font> 元，占总市值 <font color='red'>%s%%</font> ，监控正常";
		var template32 = "单一股票 <font color='red'>%s</font> 元，占总市值 <font color='red'>%s%%</font> ，高于最高阀值 <font color='red'>%s%%</font> ，监控异常报警，请尽快调整";
		var totalStock = rows.stream().filter(x -> ((Long)x.get("type_id") == 54))
				.mapToDouble(x -> (Double)x.get("y")).sum();
		var stockRate = totalStock / totalAmount * 100;
		final String row3;
		if(stockRate > 35.0) {
			row3 = String.format(template32, nf.format(totalCashier), nf2.format(stockRate), nf2.format(35));
		} else {
			row3 = String.format(template31, nf.format(totalCashier), nf2.format(stockRate));
		}
		list.add(row3);
		
		//row4
		var template4 = "今天交易 <font color='red'>%s</font> 次，其中随性交易 <font color='red'>%s</font> 次，请尽快复盘原因";
		var df = new SimpleDateFormat("yyyy-MM-dd");
		var trans = this.transactionService.findAll(user_id, null, null, null, null, 
				new Integer[] {Status.SUCCESS.value()}, new Date[] {df.parse(df.format(new Date())), new Date()}, null, 0, 100).getRows();
		var noneCount = trans.stream().filter(x -> x.getTransactionMethod() == Method.NONE.value()).count();
		var row4 = String.format(template4, trans.size(), noneCount);
		list.add(row4);
		
		//strategy
		var template51 = "<font color='red'>%s</font>股票最新价值<font color='red'>%s</font>元，满足价格变动监控策略<font color='red'>%s</font>元以上，请知悉";
		var template52 = "<font color='red'>%s</font>股票最新价值<font color='red'>%s</font>元，满足价格变动监控策略<font color='red'>%s</font>元以下，请知悉";
		var strategies = this.strategyService.findAll(user_id, 6L, null, 1, 0, 100).getRows();
		strategies.forEach(x -> {
			var detail = this.changeService.findPriceChangeInfo(x.getStrategyId()).getRows().get(0);
			var invest = this.investService.findById(x.getInvestId());
			if(invest.getPrice() > detail.getMax_price()) {
				var row = String.format(template51, invest.getAssets().getName(), nf2.format(invest.getPrice()), nf2.format(detail.getMax_price()));
				list.add(row);
			} else if(invest.getPrice() < detail.getMin_price()) {
				var row = String.format(template52, invest.getAssets().getName(), nf2.format(invest.getPrice()), nf2.format(detail.getMin_price()));
				list.add(row);
			}
		});
		//stock
		var templateStockFell = "<font color='red'>%s</font>股票最新价格<font color='red'>%s</font>元，"
				+ "3个月最高价<font color='red'>%s</font>元，3个月跌幅<font color='red'>%s%%</font>，请知悉";
		var assets = this.assetsService.findAll3(Long.parseLong(principal.getId()), 0, 1000).getRows();
		assets.stream().filter(x -> x.getFellRateM3() != null).filter(x -> x.getFellRateM3() > 30).forEach(x ->{
			var row = String.format(templateStockFell, x.getName(), x.getPrice(), 
					x.getMaxPriceM3(), nf2.format(x.getFellRateM3()));
			list.add(row);
		});
		
		result.put(Codes.ROWS, list);
		return result;
	}
}
